package com.jyt.utils;

import chinavision.yjf.MVSDK;
import chinavision.yjf.MVSDK.tSdkFrameHead;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;

import com.sun.jna.Native;

public class Grabber extends JFrame {

	public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				try {
					UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
				} catch (ClassNotFoundException | InstantiationException
					   | IllegalAccessException | UnsupportedLookAndFeelException ex) {
					ex.printStackTrace();
				}

                new Grabber().createAndShowGui();
            }
        });
	}

	private long mGrabber;
	private MVSDK.pfnCameraGrabberFrameCallback mImageCallback;
	private JLabel mLabel;
	
    private void createAndShowGui() {

		setTitle("Grabber");
		setSize(800, 600);
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setVisible(true);
		
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if (mGrabber != 0) {
					// 关闭采集器
					MVSDK.Api.CameraGrabber_Destroy(mGrabber);
					mGrabber = 0;
				}

				super.windowClosing(e);
			}
		});

		mLabel = new JLabel();
		mLabel.setSize(640, 480);
		getContentPane().add(mLabel);

		if (!openCamera() ) {
			System.exit(0);
		}
	}

	private boolean openCamera() {

		// 枚举相机
		MVSDK.tSdkCameraDevInfo[] DevList = MVSDK.Api.CameraEnumerateDevice();
		int nDev = DevList.length;
		if (nDev < 1) {
			JOptionPane.showMessageDialog(null, "No camera was found!");
			return false;
		}

		MVSDK.tSdkCameraDevInfo DevInfo = DevList[0];

		// 打开相机
		try {
			mGrabber = MVSDK.Api.CameraGrabber_Create(DevInfo);
		}
		catch (MVSDK.CameraException e) {
			JOptionPane.showMessageDialog(null, String.format("CameraGrabber_Create Failed(%d): %s", e.errorCode, e.getMessage()));
			return false;
		}

		// 取出Grabber内部的相机句柄
		int hCamera = MVSDK.Api.CameraGrabber_GetCameraHandle(mGrabber);

		// 获取相机特性描述
		MVSDK.tSdkCameraCapbility cap = MVSDK.Api.CameraGetCapability(hCamera);

		// 判断是黑白相机还是彩色相机
		boolean monoCamera = (cap.sIspCapacity.bMonoSensor != 0);

		// 黑白相机让ISP直接输出MONO数据，而不是扩展成R=G=B的24位灰度
		if (monoCamera) {
			MVSDK.Api.CameraSetIspOutFormat(hCamera, MVSDK.CAMERA_MEDIA_TYPE_MONO8);
		}

		// 相机模式切换成连续采集
		MVSDK.Api.CameraSetTriggerMode(hCamera, 0);

		// 手动曝光，曝光时间30ms
		MVSDK.Api.CameraSetAeState(hCamera, 0);
		MVSDK.Api.CameraSetExposureTime(hCamera, 30 * 1000);

		// 设置取图回调
		mImageCallback = new MVSDK.pfnCameraGrabberFrameCallback() {
			@Override
			public void OnCaptured(long Grabber, long pFrameBuffer, tSdkFrameHead pFrameHead, long Context) {
				// 此时图片已经存储在pFrameBuffer中，对于彩色相机pFrameBuffer=RGB数据，黑白相机pFrameBuffer=8位灰度数据
				
				// 由于相机输出的数据是从下到上的，而BufferedImage需要从上到下的数据，在这里把图像数据翻转一下
				MVSDK.Api.CameraFlipFrameBuffer(pFrameBuffer, pFrameHead, 1);

				BufferedImage image = MVSDK.createImage(pFrameBuffer, pFrameHead);

				ImageIcon disp = new ImageIcon();
				disp.setImage(image.getScaledInstance(mLabel.getWidth(), mLabel.getHeight(), Image.SCALE_FAST));
				SwingUtilities.invokeLater(new Runnable(){
					@Override
					public void run() {
						mLabel.setIcon(disp);
					}
				});
			}
		};
		MVSDK.Api.CameraGrabber_SetRGBCallback(mGrabber, mImageCallback, 0);

		// 启动采集器
		MVSDK.Api.CameraGrabber_StartLive(mGrabber);
		
		return true;
	}
}
